﻿//Copyright (c) Microsoft Corporation.  All rights reserved.

using System;

namespace Microsoft.Ted.Wacel.Base
{
    public class CircularBuffer<T> : Array<T>
    {
        private string mNextIndexKey;
        public CircularBuffer(string name, long size, IDataProvider dataProvider, ILockProvider lockProvider)
            : base(name, size, dataProvider, lockProvider)
        {
            mNextIndexKey = name + ".next";
        }
        public virtual void Reset()
        {
            PutInSub(mNextIndexKey, -1L);
        }
        public virtual void Add(T item)
        {
            long nextIndex = Increment(mNextIndexKey, 1, 0) % Length;
            PutInSub(mNextIndexKey, nextIndex);
            Put(nextIndex.ToString(), item);
        }

        public override T this[long key]
        {
            get
            {
                if (key > 0 || key <= -Length)
                    throw new IndexOutOfRangeException();
                long adjustedKey = InterlockedRead(mNextIndexKey, 0) + key;
                if (adjustedKey < 0)
                    adjustedKey += Length;
                return base[adjustedKey];
            }
        }
    }
}
